# -*- coding: utf-8 -*-
# @Author : HJH
# @Time : 2024/1/16 17:51
# @Use :
import datetime
import concurrent.futures
import os
import sys

import pandas as pd
import requests
import hashlib
import time
import json

from loguru import logger
from tqdm import tqdm


def log_config():
    # 添加输出处理程序，将日志输出到文件
    logger.add("./logs/info_file.log", level="INFO")
    logger.add("./logs/error_file.log", level="ERROR")


def get_date_time(datetime_str):
    # 输入日期时间字符串
    # datetime_str = "2024-02-15 21:15:00"

    # 将日期时间字符串转换为datetime对象
    datetime_obj = datetime.datetime.strptime(datetime_str, "%Y-%m-%d %H:%M")

    # 获取当前时区的时间戳
    timestamp = datetime_obj.timestamp()

    # 将时间戳转换为整数
    timestamp = int(timestamp)

    # 在时间戳后面添加3个零，使其长度为13位
    return str(timestamp) + "000"


def send_request(flight_no, cabin, dep, arr, dep_time, arr_time):
    appkey = "B20230907024"
    secret = "NoPt5JpRfRU6d4pR75Mz8nWdLQafhGbR"
    url = "http://openapi.tenfli.com/api/order/policies"
    req = {
        "accounts":
            [
                {
                    "password": "ychk@888",
                    "supplierCode": "OTA_LY",
                    "username": "13619716910"
                }
            ],
        "keepNotMatched": True,
        "crawlOnly": True,
        "otaOrderNo": "exw240116172920466003",
        "tickets":
            [
                {
                    "arr": arr,
                    "arrTime": arr_time,
                    "birthDay": "1996-01-10",
                    "buildPrice": 0,
                    "cabinCode": "W",
                    "certCode": "410185200201189869",
                    "certType": "ID",
                    "dep": dep,
                    "depTime": dep_time,
                    "flightNo": flight_no,
                    "fuelPrice": 0,
                    "gender": "FEMALE",
                    "mobile": "13783590698",
                    "name": "赵瑞凯",
                    "printPrice": 0,
                    "salePrice": 0,
                    "type": "ADU"
                }
            ]
    }

    # 签名生成
    time_millis = int(time.time() * 1000)
    text = f"{appkey}&{time_millis}&{secret}"
    sign = hashlib.md5(text.encode('utf-8')).hexdigest()

    # 构建请求
    headers = {
        "Content-Type": "application/json",
        "appKey": appkey,
        "sign": sign,
        "timestamp": str(time_millis)
    }

    """
    请求接口
    """
    max_tries = 5  # 最大尝试次数
    num_tries = 0  # 已尝试次数
    sleep_time2 = 3  # 设置等待时间
    result = ''
    while num_tries < max_tries:
        try:
            response = requests.post(url, headers=headers, json=req)
            result = response.text
            res_data = json.loads(result)

            if res_data['content'] is not None:
                r_price = [price for price in res_data['content'] if
                           price['cabinCode'] in cabin and price['policyTypeDesc'] == '其他#全额行程单']
                if len(r_price) > 1:
                    # r_price = min(r_price, key=lambda price: price['cabinPrice'])
                    # 首先按照 cabin 进行分组
                    grouped_data = {}
                    for item in r_price:
                        c1 = item['cabinCode']
                        if c1 not in grouped_data:
                            grouped_data[c1] = []
                        grouped_data[c1].append(item)

                    # 然后在每个分组中找出 priceTag 为“全额行程单”的数据中 price 最低的那一条
                    filtered_data = []
                    for cabin, data in grouped_data.items():
                        filtered_data.append(min(data, key=lambda price: price['cabinPrice']))
                    logger.info(f"【腾鸢同程舱价格】结果: {str(filtered_data)}")
                    return filtered_data
                else:
                    logger.info(f"【腾鸢同程舱价格】结果: {dep_time}/{flight_no}/{dep}/{arr}没有合适数据")
                    return None
            else:
                logger.error(f"【腾鸢同程舱价格】结果: {str(res_data)}")
        except (requests.exceptions.RequestException, json.JSONDecodeError) as e:
            logger.error(f"【腾鸢同程舱价格】结果: {str(result)}")
            num_tries += 1
            if num_tries >= max_tries:
                # 如果已经尝试到最大次数，跳出循环，放弃重试
                logger.error(f"重试{max_tries}次后仍然失败，放弃重试。")
                break
            # 打印日志，并且睡眠
            logger.info(f"请求失败，休眠 {sleep_time2} 秒后进行第 {num_tries + 1} 次尝试。")
            logger.error(e)
            time.sleep(sleep_time2)


def task_function(tf_row):
    pr_dep_time = get_date_time(tf_row['出发日期'] + ' ' + tf_row['出发时间'])
    pr_arr_time = get_date_time(tf_row['到达日期'] + ' ' + tf_row['到达时间'])
    tc_rp = send_request(tf_row['航班号'], tf_row['舱位'], tf_row['起飞'], tf_row['到达'], pr_dep_time, pr_arr_time)

    # 更新进度条
    progress_bar.update(1)

    # 定义舱位代码和列名的映射关系
    # cabin_mapping = {
    #     'P': '同程P舱价格',
    #     'F': '同程F舱价格'
    # }

    if tc_rp is not None and len(tc_rp) > 0:
        # 遍历 tc_rp 列表，根据舱位代码更新 r_p_excel_df 数据框.
        count = 0
        for p in tc_rp:
            if p['cabinCode'] in tf_row['舱位']:
                r_p_excel_df.at[tf_row.name, f'舱位{count}'] = p['cabinCode']
                r_p_excel_df.at[tf_row.name, f'价格{count}'] = p['cabinPrice']
                count = count + 1


if __name__ == '__main__':
    # pr_dep_time = get_date_time('2024-03-13 16:55')
    # pr_arr_time = get_date_time('2024-03-13 18:55')
    # tc_rp = send_request('GY7223', 'V', 'YBP', 'CGO', pr_dep_time, pr_arr_time)

    read_file = input("请输入读取文件名：")
    write_file = input("请输入输出文件名：")

    # 初始化日志配置
    log_config()

    # 相对文件路径
    # current_dir = os.path.dirname(os.path.abspath(__file__))
    current_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
    # current_dir = "../docs/"
    read_path = os.path.join(current_dir, f"{read_file}.xlsx")
    write_path = os.path.join(current_dir, f"{write_file}.xlsx")

    # 读取excel文件
    r_p_excel_file = pd.ExcelFile(read_path)
    # 读取指定Sheet数据
    r_p_excel_df = r_p_excel_file.parse('Sheet1')

    total_rows = len(r_p_excel_df)

    # 创建进度条
    progress_bar = tqdm(total=total_rows, desc="执行进度", unit="次")

    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        for index, row in r_p_excel_df.iterrows():
            executor.submit(task_function, row)

    # 关闭进度条
    progress_bar.close()

    logger.info("开始生成excel文件...")
    r_p_excel_df.to_excel(write_path, index=False)
